

#include "mlink.h"
#include "mlink_mqtt_handle.h"
#include "mesh_mqtt_handle.h"


#define MLINK_MQTT_STORE_KEY    "MLINK_MQTT"
#ifndef CONFIG_MQTT_URL
#define CONFIG_MQTT_URL "mqtt://broker.emqx.io"
#endif
#define MQTT_PORT 1883
#define MQTT_USER "admin"
#define MQTT_PASS "admin"

typedef struct {
	char url[128];
	int port;
    char username[32];
    char password[128];
	char publish_topic[64];
	char subscribe_topic[64];
}mlink_mqtt_t;

typedef struct {
	int size;
}mlink_mqtt_store_t;

static const char *TAG                       = "mlink_mqtt";
// static const char publish_topic_template[] = "mesh/%02x%02x%02x%02x%02x%02x/to_cloud";
// static const char topo_topic_template[] = "mesh/%02x%02x%02x%02x%02x%02x/topo";
// static const char subscribe_topic_template[] = "mesh/%02x%02x%02x%02x%02x%02x/to_device";

static mlink_mqtt_t mqtt = {
	.url = CONFIG_MQTT_URL,
	.port = MQTT_PORT,
	.username = MQTT_USER,
	.password = MQTT_PASS
};

void mqtt_set_url(const char * url)
{
	if(url == NULL)
		return;
	strcpy(mqtt.url, url);
}
const char * mqtt_get_url()
{
	// if(strlen(mqtt.url) > 0){
	return (const char *)mqtt.url;
// 	}else{
// 		return NULL;
// 	}
}

void mqtt_set_port(int port)
{
	mqtt.port = port;
}
int mqtt_get_port()
{
	return mqtt.port;
}

void mqtt_set_username(const char * val)
{
	if(val == NULL)
		return;
	strcpy(mqtt.username, val);
}

const char * mqtt_get_username()
{
	// if(strlen(mqtt.username) > 0){
		return (const char *)mqtt.username;
	// }else{
	// 	return NULL;
	// }
}

void mqtt_set_password(const char * val)
{
	if(val == NULL)
		return;
	strcpy(mqtt.password, val);
}

const char * mqtt_get_password()
{
	// if(strlen(mqtt.password) > 0){
		return (const char *)mqtt.password;
	// }else{
	// 	return NULL;
	// }
}

void mqtt_set_custom_publish_topic(const char * val)
{
	if(val == NULL)
		return;
	strcpy(mqtt.publish_topic, val);
}

const char * mqtt_get_custom_publish_topic()
{
	return (const char *)mqtt.publish_topic;
}

void mqtt_set_custom_subscribe_topic(const char * val)
{
	if(val == NULL)
		return;
	strcpy(mqtt.subscribe_topic, val);
}

const char * mqtt_get_custom_subscribe_topic()
{
	return (const char *)mqtt.subscribe_topic;
}

mdf_err_t mqtt_save(void)
{	
	mdf_err_t ret   = MDF_OK;
	char *mqtt_json = NULL;
	
	if(strlen(mqtt.url) > 0){
	mlink_json_pack(&mqtt_json, "url", mqtt.url);
	}
	if(mqtt.port > 0){
	mlink_json_pack(&mqtt_json, "port", mqtt.port);
	}
	if(strlen(mqtt.username) > 0){
		mlink_json_pack(&mqtt_json, "username", mqtt.username);
	}
	if(strlen(mqtt.password) > 0){
		mlink_json_pack(&mqtt_json, "password", mqtt.password);
	}

	if(strlen(mqtt.subscribe_topic) > 0) {
		mlink_json_pack(&mqtt_json, "subscribe_topic", mqtt.subscribe_topic);
	}

	if(strlen(mqtt.publish_topic) > 0) {
		mlink_json_pack(&mqtt_json, "publish_topic", mqtt.publish_topic);
	}

    ret = mdf_info_save("mqtt_param", mqtt_json, strlen(mqtt_json) + 1);
    MDF_ERROR_GOTO(ret != MDF_OK, EXIT, "Save the information");

	mlink_mqtt_store_t mqtt_store;
	mqtt_store.size = strlen(mqtt_json) + 1;

    ret = mdf_info_save(MLINK_MQTT_STORE_KEY, &mqtt_store, sizeof(mlink_mqtt_store_t));
    MDF_ERROR_GOTO(ret != MDF_OK, EXIT, "Save the information");
EXIT:

	MDF_FREE(mqtt_json);

	return ret;
}

mdf_err_t mqtt_load(void)
{	
	mdf_err_t ret	   = ESP_OK;
	char *raw_data = NULL;
	mlink_mqtt_store_t mqtt_store;

	if( __mdf_info_load(MLINK_MQTT_STORE_KEY, &mqtt_store, sizeof(mlink_mqtt_store_t), LENGTH_TYPE_NUMBER) == MDF_OK) {
		
		raw_data = MDF_MALLOC(mqtt_store.size);
		ret = __mdf_info_load("mqtt_param", raw_data, mqtt_store.size, LENGTH_TYPE_NUMBER);
		MDF_ERROR_GOTO(ret != MDF_OK, EXIT, " Load the information");
		
		ret = mlink_json_parse(raw_data, "url", mqtt.url);
		MDF_ERROR_GOTO(ret != MDF_OK, EXIT, "Parse the json formatted string");
		
		ret = mlink_json_parse(raw_data, "port", &mqtt.port);
		MDF_ERROR_GOTO(ret != MDF_OK, EXIT, "Parse the json formatted string");

		mlink_json_parse(raw_data, "username", mqtt.username);
		mlink_json_parse(raw_data, "password", mqtt.password);
		mlink_json_parse(raw_data, "publish_topic", mqtt.publish_topic);
		mlink_json_parse(raw_data, "subscribe_topic", mqtt.subscribe_topic);

	} else {
		strcpy(mqtt.url, CONFIG_MQTT_URL);
		mqtt.port = 1883;
		strcpy(mqtt.username, "");
		strcpy(mqtt.password, "");
		strcpy(mqtt.publish_topic, "");
		strcpy(mqtt.subscribe_topic, "");
	}

	
EXIT:
	MDF_FREE(raw_data);

	MDF_LOGD("mqtt url %s port %d",mqtt.url,mqtt.port);

	return ret;

}

static mdf_err_t mlink_handle_set_mqtt(mlink_handle_data_t *handle_data)
{
    mdf_err_t ret   = MDF_OK;
	char *mqtt_json = NULL;
	char url[128];
	
    ret = mlink_json_parse(handle_data->req_data, "mqtt", &mqtt_json);
    MDF_ERROR_CHECK(ret != MDF_OK, ret, "Parse the json formatted string");

    ret = mlink_json_parse(mqtt_json, "url", url);
    MDF_ERROR_GOTO(ret != MDF_OK, EXIT, "Parse the json formatted string");
	
	// struct http_parser_url puri;
	// http_parser_url_init(&puri);
	// int parser_status = http_parser_parse_url(url, strlen(url), 0, &puri);
	// if (parser_status == 0) {
		strcpy(mqtt.url, url);
	// }else{
	// 	MDF_LOGE("Error parse uri = %s", url);
	// 	ret = MDF_ERR_INVALID_ARG;
	// 	goto EXIT;
	// }

    ret = mlink_json_parse(mqtt_json, "port", &mqtt.port);
    MDF_ERROR_GOTO(ret != MDF_OK, EXIT, "Parse the json formatted string");

	mlink_json_parse(mqtt_json, "username", mqtt.username);
	mlink_json_parse(mqtt_json, "password", mqtt.password);
	mlink_json_parse(mqtt_json, "publish_topic", mqtt.publish_topic);
	mlink_json_parse(mqtt_json, "subscribe_topic", mqtt.subscribe_topic);

    ret = mdf_info_save("mqtt_param", mqtt_json, strlen(mqtt_json) + 1);

	mlink_mqtt_store_t mqtt_store;
	mqtt_store.size = strlen(mqtt_json) + 1;

    ret = mdf_info_save(MLINK_MQTT_STORE_KEY, &mqtt_store, sizeof(mlink_mqtt_store_t));

EXIT:
	MDF_FREE(mqtt_json);
	
    return MDF_OK;
}

static mdf_err_t mlink_handle_get_mqtt(mlink_handle_data_t *handle_data)
{
    mdf_err_t ret      = ESP_OK;
	char *raw_data = NULL;
	mlink_mqtt_store_t mqtt_store;

	if(__mdf_info_load(MLINK_MQTT_STORE_KEY, &mqtt_store, sizeof(mlink_mqtt_store_t), LENGTH_TYPE_NUMBER) == MDF_OK) {
		raw_data = MDF_MALLOC(mqtt_store.size);
		ret = __mdf_info_load("mqtt_param", raw_data, mqtt_store.size, LENGTH_TYPE_NUMBER);
		MDF_ERROR_GOTO(ret != MDF_OK, EXIT, " Load the information");
	} else {
		raw_data = MDF_MALLOC(128);
		if(strlen(mqtt.url) > 0){
		mlink_json_pack(&raw_data, "url", mqtt.url);
		}
		if(mqtt.port > 0){
		mlink_json_pack(&raw_data, "port", mqtt.port);
		}
		if(strlen(mqtt.username) > 0){
			mlink_json_pack(&raw_data, "username", mqtt.username);
		}
		else {
			mlink_json_pack(&raw_data, "username", "");
		}
		if(strlen(mqtt.password) > 0){
			mlink_json_pack(&raw_data, "password", mqtt.password);
		}
		else {
			mlink_json_pack(&raw_data, "password", "");
		}

		mlink_json_parse(raw_data, "publish_topic", mqtt.publish_topic);
		mlink_json_parse(raw_data, "subscribe_topic", mqtt.subscribe_topic);
	}
	if(raw_data!= NULL){
		bool connected = mesh_mqtt_is_connect();
		handle_data->resp_size = mlink_json_pack(&raw_data, "connected", connected);
		handle_data->resp_size = mlink_json_pack(&handle_data->resp_data, "mqtt", raw_data);
	}
EXIT:
    MDF_FREE(raw_data);
    return ret;
}

mdf_err_t mlink_mqtt_init(void)
{
    mdf_err_t ret      = ESP_OK;
	char *raw_data = NULL;
	mlink_mqtt_store_t mqtt_store;

	mlink_set_handle("set_mqtt", mlink_handle_set_mqtt);
    mlink_set_handle("get_mqtt", mlink_handle_get_mqtt);

	if( __mdf_info_load(MLINK_MQTT_STORE_KEY, &mqtt_store, sizeof(mlink_mqtt_store_t), LENGTH_TYPE_NUMBER) == MDF_OK) {
		
		raw_data = MDF_MALLOC(mqtt_store.size);
		ret = __mdf_info_load("mqtt_param", raw_data, mqtt_store.size, LENGTH_TYPE_NUMBER);
		MDF_ERROR_GOTO(ret != MDF_OK, EXIT, " Load the information");
		
		ret = mlink_json_parse(raw_data, "url", mqtt.url);
		MDF_ERROR_GOTO(ret != MDF_OK, EXIT, "Parse the json formatted string");
		
		ret = mlink_json_parse(raw_data, "port", &mqtt.port);
		MDF_ERROR_GOTO(ret != MDF_OK, EXIT, "Parse the json formatted string");

		mlink_json_parse(raw_data, "username", mqtt.username);
		mlink_json_parse(raw_data, "password", mqtt.password);
	} else {
		strcpy(mqtt.url, CONFIG_MQTT_URL);
		mqtt.port = MQTT_PORT;
		strcpy(mqtt.username, MQTT_USER);
		strcpy(mqtt.password, MQTT_PASS);
	}
    
EXIT:
	MDF_FREE(raw_data);

	MDF_LOGI("mqtt url %s port %d, username %s password %s", mqtt.url,mqtt.port, mqtt.username, mqtt.password);

	return ret;

}

